using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using EditWebSite.Presentation;
using System.Diagnostics;

namespace EditWebSite.Controls
{
    internal partial class SyntaxText : RichTextBox
    {
        public enum TipoVisualizzazioni
        {
            Tabelle,
            Campi,
            Proprietari,
            Nulla
        }

        private Helper _helper;
        private IntelliList _iList;
        private int _startIntelli;


        public SyntaxText()
        {
            InitializeComponent();
            this.BackColor = Color.Black;
            this.ForeColor = Color.White;
            this.AcceptsTab = true;
            _iList = new IntelliList();
            _iList.Visible = false;
            _iList.DoubleClick += new EventHandler(iList_DoubleClick);
        }

        void iList_DoubleClick(object sender, EventArgs e)
        {

            try
            {
                int fine = base.SelectionStart;
                if (fine > _startIntelli)
                {
                    base.SelectionStart = _startIntelli;
                    base.SelectionLength = fine - _startIntelli;
                }
                base.SelectedText = _iList.SelectedItem.ToString();
                _iList.Hide();
            }
            catch (Exception)
            {

            }
        }

        public void SetHelper(Helper helper)
        {
            _helper = helper;


            this.Controls.Add(_iList);
        }

        protected override void OnMouseClick(MouseEventArgs e)
        {
            _iList.Hide();

            base.OnMouseClick(e);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.OemPeriod)
            {

                int curPos = base.SelectionStart;
                coloraLinea(curPos);
                base.SelectionStart = curPos;
                base.SelectionColor = _helper.COLOR_NORMAL;

                visualizzaIntellisense(curPos, true);
            }
            else if (e.KeyCode == Keys.Space)
            {
                int curPos = base.SelectionStart;
                string testo = base.Text;
                coloraLinea(curPos);
                base.SelectionStart = curPos;
                base.SelectionColor = _helper.COLOR_NORMAL;

                int linea = this.GetLineFromCharIndex(curPos);

                for (int i = linea; i > -1; i--)
                {
                    if (_helper.IsIntellisenseDaVisualizzare(base.Lines[linea]))
                    {
                        visualizzaIntellisense(curPos, false);
                        break;
                    }
                }

            }
            else if (e.KeyCode == Keys.Return)
            {
                int curPos = base.SelectionStart;
                coloraLinea(curPos);
                base.SelectionStart = curPos;
                base.SelectionColor = _helper.COLOR_NORMAL;

                int linea = this.GetLineFromCharIndex(curPos);
                string s = base.Lines[linea];

                if (linea > 0)
                {
                    string lineaPrec = base.Lines[linea - 1];
                    string lineaTrim = lineaPrec.TrimStart();

                    int spazi = lineaPrec.Length - lineaTrim.Length;
                    if (spazi > 0)
                    {
                        base.SelectedText = new string(' ', spazi);
                    }
                }
            }
            else if (e.KeyCode == Keys.Escape)
            {
                _iList.Hide();
            }
            else if (e.KeyCode == Keys.Space & e.Control)
            {
                visualizzaIntellisense(base.SelectionStart, false);
            }

            if (e.KeyCode == Keys.Up ||
                e.KeyCode == Keys.Down ||
                e.KeyCode == Keys.PageDown ||
                e.KeyCode == Keys.PageUp)
            {
                if (_iList.Visible)
                {
                    e.SuppressKeyPress = true;
                    e.Handled = true;
                }
            }
            else
            {

                base.OnKeyUp(e);
            }
        }


        private void visualizzaIntellisense(int Posizione, bool SoloTabellaCorrente)
        {
            try
            {
                TipoVisualizzazioni tipo = _helper.GetTipoVisualizzazione(Text, Posizione);
                if (tipo == TipoVisualizzazioni.Nulla)
                {
                    _iList.Items.Clear();
                    _iList.Visible = false;
                    return;
                }
                if (tipo == TipoVisualizzazioni.Tabelle)
                {
                    string[] ElencoTabelle = _helper.GetTabelle();
                    _iList.Items.Clear();
                    _iList.Items.AddRange(ElencoTabelle);
                }
                else if (tipo == TipoVisualizzazioni.Campi)
                {
                    string[] ElencoTabelle ;
                    if (SoloTabellaCorrente)
                    {
                        ElencoTabelle = _helper.GetCampiTabellaPrecedente(Text, Posizione);
                    }
                    else
                    {
                        ElencoTabelle = _helper.GetCampi();
                    }
                    if (ElencoTabelle.Length > 0)
                    {
                        _iList.Items.Clear();
                        _iList.Items.AddRange(ElencoTabelle);
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    throw new Exception("Proprietari non esistono");
                }
                _startIntelli = Posizione;
                Point p = this.GetPositionFromCharIndex(Posizione);
                p.Y += (int)Math.Ceiling(this.Font.GetHeight()) + 2;
                p.X += 2;

                _iList.Location = p;
                _iList.Show();
                _iList.BringToFront();
                _iList.SelectedIndex = 0;
            }
            catch (Exception)
            {
                #region LOGIC
#if DEBUG
                Debugger.Break();
#endif
                throw;
                #endregion
            }
        }

        private string[] getTabelleRichiamate()
        {
            try
            {
                List<string> tabelle = new List<string>();



                return tabelle.ToArray();
            }
            catch (Exception)
            {
                throw;
            }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            try
            {
                if (!_iList.Visible)
                {
                    if (e.KeyCode == Keys.Space && e.Control)
                    {
                        e.Handled = true;
                        e.SuppressKeyPress = true;
                        int curPos = base.SelectionStart;
                        visualizzaIntellisense(curPos, false);
                        return;
                    }
                    if ((e.KeyCode == Keys.Return |
                        e.KeyCode == Keys.Up |
                        e.KeyCode == Keys.Down)
                        & e.Shift == false)
                    {
                        int curPos = base.SelectionStart;
                        coloraLinea(curPos);
                        base.SelectionStart = curPos;
                        base.SelectionColor = _helper.COLOR_NORMAL;
                    }
                    base.OnKeyDown(e);
                }
                else
                {
                    if (e.KeyCode == Keys.Space || e.KeyCode == Keys.Return || e.KeyCode == Keys.Tab)
                    {
                        if (_iList.SelectedIndex > -1)
                        {
                            iList_DoubleClick(this, new EventArgs());
                            //e.Handled = true;
                            //e.SuppressKeyPress = true;
                        }
                        else
                        {
                            _iList.Visible = false;
                            base.OnKeyDown(e);
                        }
                    }
                    else if (e.KeyCode == Keys.Up)
                    {
                        _iList.SelectedIndex = Math.Max(0, _iList.SelectedIndex - 1);
                        e.Handled = true;
                        e.SuppressKeyPress = true;
                    }
                    else if (e.KeyCode == Keys.Down)
                    {
                        _iList.SelectedIndex = Math.Min(_iList.SelectedIndex + 1, _iList.Items.Count - 1);
                        e.Handled = true;
                        e.SuppressKeyPress = true;
                    }
                    else if (e.KeyCode == Keys.PageDown)
                    {
                        _iList.SelectedIndex = Math.Min(_iList.Items.Count - 1, _iList.SelectedIndex + 10);
                        e.Handled = true;
                        e.SuppressKeyPress = true;
                    }
                    else if (e.KeyCode == Keys.PageUp)
                    {
                        _iList.SelectedIndex = Math.Max(0, _iList.SelectedIndex - 10);
                        e.Handled = true;
                        e.SuppressKeyPress = true;
                    }
                    else if (e.KeyCode == Keys.OemPeriod || e.KeyCode == Keys.Oemcomma)
                    {
                        iList_DoubleClick(this, new EventArgs());
                    }
                    //else if (e.KeyCode == Keys.Back)
                    //{
                    //    _iList.Hide();
                    //}
                    else
                    {
                        int pos = this.SelectionStart;
                        string tab = string.Empty;
                        if (pos > _startIntelli)
                        {
                            tab = Text.Substring(_startIntelli, pos - _startIntelli);
                        }
                        tab += (char)e.KeyValue;
                        if (_iList.SelectedIndex == -1 || !_iList.SelectedItem.ToString().StartsWith(tab))
                        {
                            int i;
                            if (e.KeyCode == Keys.Back)
                            {
                                if (tab.Length > 2)
                                {
                                    tab = tab.Substring(0, tab.Length - 2);
                                    for (i = _iList.SelectedIndex; i > 0; i--)
                                    {
                                        if (_iList.Items[i].ToString().StartsWith(tab, StringComparison.OrdinalIgnoreCase))
                                        {
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    i = -1;
                                }
                            }
                            else
                            {

                                for (i = Math.Max(0, _iList.SelectedIndex); i < _iList.Items.Count - 1; i++)
                                {
                                    if (_iList.Items[i].ToString().StartsWith(tab, StringComparison.OrdinalIgnoreCase))
                                    {
                                        break;
                                    }
                                }
                            }
                            if (i == -1 || _iList.Items[i].ToString().StartsWith(tab, StringComparison.OrdinalIgnoreCase))
                            {
                                _iList.SelectedIndex = i;
                            }
                            else
                            {
                                _iList.SelectedIndex = -1;
                            }
                        }
                        base.OnKeyDown(e);
                    }
                    return;
                }
            }
            catch (Exception)
            {
                #region LOGIC
#if DEBUG
                Debugger.Break();
#endif
                throw;
                #endregion
            }


        }

        private void coloraLinea(int posizione)
        {
            try
            {
                //int linea = getNumeroLinea(posizione);
                //if (linea >= base.Lines.Length)
                //    linea--;
                int linea = this.GetLineFromCharIndex(posizione);
                string s = base.Lines[linea];



                string[] parole = s.Split(' ');
                int start = 0, len = 0;

                for (int i = 0; i < linea; i++)
                {
                    start += base.Lines[i].Length + 1;
                }
                //if (s.TrimStart().StartsWith("--"))
                //{
                //    len = s.Length;
                //    base.SelectionStart = start;
                //    base.SelectionLength = len;
                //    base.SelectionColor = _helper.GetColorCommento();
                //    base.SelectedText = s;
                //    return;
                //}
                foreach (string parola in parole)
                {
                    string sParola = parola.ToUpper();

                    if (_helper.ContienePunteggiatura(sParola))
                    {
                        len = sParola.Length;
                        string[] sub = _helper.Separa(sParola);
                        int l, pst = start;
                        foreach (string st in sub)
                        {

                            l = st.Length;
                            base.SelectionStart = pst;
                            base.SelectionLength = l;
                            base.SelectionColor = _helper.GetColor(st);
                            base.SelectedText = st;
                            pst += l;
                        }
                    }
                    else
                    {
                        len = sParola.Length;
                        base.SelectionStart = start;
                        base.SelectionLength = len;
                        base.SelectionColor = _helper.GetColor(sParola);
                        base.SelectedText = sParola;
                    }
                    start += len + 1;
                }
            }
            catch (Exception ex)
            {
                Messaggi.Attention(ex.Message);
            }
        }
    }
}
